home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Think Class Libraries / CScrollList 1.0 / CScrollList Classes / CScrollListDragger.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-30  |  5.5 KB  |  210 lines  |  [TEXT/KAHL]

  1. /*************************************************************************************
  2.  
  3.  CScrollListDragger.c
  4.     
  5.         Used with scrolling lists that allow the movement of array elements
  6.         within the list.  First it selects the hit cell.  Once the mouse is
  7.         moved, it starts tracking its position.  When it is released, it moves
  8.         the selected cell to the new position.  It will scroll the list to
  9.         follow the mouse.
  10.     
  11.     SUPERCLASS = CMouseTask
  12.     
  13.     REQUIRES: gHandCursor be handle to the hand cursor
  14.     
  15.         © 1992 Dave Harkness
  16.  
  17. *************************************************************************************/
  18.  
  19.  
  20. #include "CScrollListDragger.h"
  21. #include "CScrollList.h"
  22. #include <CArray.h>
  23. #include <TBUtilities.h>
  24.  
  25.  
  26. #define DRAGTHRESH        4                // Distance cursor must move vertically
  27.                                         // ...before the cell starts to drag.
  28.  
  29.  
  30. extern CursHandle        gHandCursor;
  31.  
  32.  
  33. /******************************************************************************
  34.  IScrollListDragger
  35. ******************************************************************************/
  36.  
  37. void
  38. CScrollListDragger::IScrollListDragger( CScrollList *aList, short theModifiers,
  39.                                         short aHeight, short fOptions)
  40.  
  41. {
  42.     CMouseTask::IMouseTask( 0);
  43.     
  44.     itsScrollList = aList;
  45.     itsArray = itsScrollList->GetArray();
  46.     modifierKeys = theModifiers;
  47.     cellHeight = aHeight;
  48.     listOptions = fOptions;
  49.     
  50.     movingCell = 0;                                            // not moving yet
  51.     dragging = FALSE;
  52.  
  53. }    /* CScrollListDragger::IScrollListDragger */
  54.  
  55.  
  56. /******************************************************************************
  57.  Dispose
  58.       
  59.       Dispose of a CScrollListDragger. This method clears the list's
  60.       reference to this task.
  61. ******************************************************************************/
  62.  
  63. void
  64. CScrollListDragger::Dispose(void)
  65.  
  66. {
  67.     if ( itsScrollList->itsLastTask == this)
  68.         itsScrollList->itsLastTask = NULL;
  69.     
  70.     inherited::Dispose();
  71.  
  72. }  /* CScrollListDragger::Dispose */
  73.  
  74.  
  75. /******************************************************************************
  76.  BeginTracking  {OVERRIDE}
  77.  
  78.     Called at the start of mouse tracking.  This method selects the cell
  79.     being dragged and calculates the rectangle to drag.
  80. ******************************************************************************/
  81.  
  82. void
  83. CScrollListDragger::BeginTracking( LongPt *startPt)
  84.  
  85. {
  86.     long    hExtent, vExtent;
  87.     
  88.             // Find and select the moving cell
  89.     
  90.     movingCell = itsScrollList->FindHitCell( startPt);
  91.     if ( listOptions & kSLSelectable )
  92.         itsScrollList->SelectCell( movingCell, kDoRedraw);
  93.     
  94.             // Calculate the dragging and clipping rectangles
  95.     
  96.     itsScrollList->GetCellRect( movingCell, &dragRect);
  97.     OffsetLongRect( &dragRect, 0,
  98.                     startPt->v - ((dragRect.top + dragRect.bottom) >> 1));
  99.     
  100.     itsScrollList->GetPixelExtent( &hExtent, &vExtent);
  101.     SetLongRect( &clipRect, dragRect.left, 0,
  102.                  dragRect.right, vExtent);
  103.  
  104. }    /* CScrollListDragger::BeginTracking */
  105.  
  106.  
  107. /******************************************************************************
  108.  KeepTracking  {OVERRIDE}
  109.  
  110.      Called continously while the mouse button is held down. This method
  111.      continously draws a gray rectangle and autoscrolls the table.
  112.      Only begins drawing after the mouse has moved.
  113. ******************************************************************************/
  114.  
  115. void
  116. CScrollListDragger::KeepTracking( LongPt *currPt, LongPt *prevPt, LongPt *startPt)
  117.  
  118. {
  119.     long        curTicks;
  120.     Rect        qdRect;
  121.     
  122.     if ( !dragging )
  123.     {
  124.         long    vdist = currPt->v - startPt->v;
  125.         
  126.         if ( vdist >= DRAGTHRESH || vdist <= -DRAGTHRESH )
  127.         {                                                // initiate dragging
  128.             if ( !(listOptions & kSLSelectable) )
  129.                 itsScrollList->FrameCell( movingCell, TRUE);
  130.             
  131.             itsScrollList->FrameToQDR( &dragRect, &qdRect);
  132.             PenPat( gray);
  133.             PenMode( patXor);
  134.             FrameRect( &qdRect);
  135.             
  136.             SetCursor( *gHandCursor);                // change to hand cursor
  137.             dragging = TRUE;
  138.         }
  139.         else
  140.             return;
  141.     }
  142.     
  143.     PinInRect( &clipRect, prevPt);
  144.     PinInRect( &clipRect, currPt);
  145.     
  146.     if ( currPt->v != prevPt->v )
  147.     {
  148.         itsScrollList->FrameToQDR( &dragRect, &qdRect);        // erase old rect
  149.         PenPat( gray);
  150.         PenMode( patXor);
  151.         
  152.         for ( curTicks = TickCount(); curTicks == TickCount(); )
  153.             /* try to avoid flicker */ ;
  154.         FrameRect( &qdRect);
  155.         
  156.         itsScrollList->AutoScroll( currPt);                    // calculate new rect
  157.         OffsetLongRect( &dragRect, 0, currPt->v - prevPt->v);
  158.         
  159.         itsScrollList->FrameToQDR( &dragRect, &qdRect);        // draw new rect
  160.         PenPat( gray);
  161.         PenMode( patXor);
  162.         
  163.         for ( curTicks = TickCount(); curTicks == TickCount(); )
  164.             /* try to avoid flicker */ ;
  165.         FrameRect( &qdRect);
  166.     }
  167.  
  168. }    /* CScrollListDragger::KeepTracking */
  169.  
  170.  
  171. /******************************************************************************
  172.  EndTracking  {OVERRIDE}
  173.  
  174.      Erase the dragging rectangle and move the cell to its new location.
  175.      Select the new cell position only if the list is selectable.
  176. ******************************************************************************/
  177.  
  178. void
  179. CScrollListDragger::EndTracking( LongPt *currPt, LongPt *prevPt, LongPt *startPt)
  180.  
  181. {
  182.     Rect        qdRect;
  183.     short        endCell;
  184.     
  185.     if ( dragging )
  186.     {
  187.         itsScrollList->FrameToQDR( &dragRect, &qdRect);
  188.         PenPat( gray);
  189.         PenMode( patXor);
  190.         FrameRect( &qdRect);
  191.         
  192.         endCell = itsScrollList->FindHitCell( currPt);
  193.         if ( currPt->v - cellHeight * (endCell-1) >= cellHeight >> 1 )
  194.             ++endCell;
  195.         
  196.         if ( endCell > movingCell )
  197.             --endCell;
  198.         
  199.         if ( endCell != movingCell )                    // move cells
  200.         {
  201.             itsArray->MoveItemToIndex( movingCell, endCell);
  202.             if ( listOptions & kSLSelectable )
  203.                 itsScrollList->SelectCell( endCell, kDoRedraw);
  204.         }
  205.         else if ( !(listOptions & kSLSelectable) )        // remove frame
  206.             itsScrollList->FrameCell( movingCell, FALSE);
  207.     }
  208.  
  209. }    /* CScrollListDragger::KeepTracking */
  210.